package com.zhouxiaoge.stream;

import org.junit.Test;

import java.util.ArrayList;
import java.util.Arrays;
import java.util.Iterator;
import java.util.List;
import java.util.stream.Stream;

/****************************************************************
 卐卍卐卍卐卍卐卍卐卍卐卍卐卍卐卍卐卍卐卍卐卍卐卍卐卍卐卍卐卍卐卍卐卍
 卐卐卐                    _ooOoo_                    卍卍卍卍卍卍
 卐卐卐      卐           o8888888o          卍       * 佛  卍卍卍
 卐卐卐                  88'' . ''88                  * 祖  卍卍卍
 卐卐卐                  ( | -_- | )                  * 保  卍卍卍
 卐卐卐                   0\  =  /0                   * 佑  卍卍卍
 卐卐卐                ____/'---'\____                *     卍卍卍
 卐卐卐              .'  \\|     |//  '.              * 永  卍卍卍
 卐卐卐             /  \\|||  :  |||//  \             * 无  卍卍卍
 卐卐卐            /  _||||| -:- |||||-  \            * BUG 卍卍卍
 卐卐卐            |   | \\\  -  /// |   |            *     卍卍卍
 卐卐卐            | \_|  ''\---/''  |   |            * 阿  卍卍卍
 卐卐卐            \  .-\__  `-`  ___/-. /            * 弥  卍卍卍
 卐卐卐          ___`. .'  /--.--\  `. . __           * 陀  卍卍卍
 卐卐卐        ."" '<  ‘.___\_<|>_/___.’  >'"".     * 佛  卍卍卍
 卐卐卐       | | :  ` - `.;`\ _ /`;.`/ - ` : | |     卍卍卍卍卍卍
 卐卐卐       | \ `-.   \_ __\ /__ _/   .-`  / /      卍卍卍卍卍卍
 卐卐卐 ======`-.____`-.___\_____/___.-`____.-'=======卍卍卍卍卍卍
 卐@author 周明阳 mail:gqzmy@outlook.com 时间:2019-06-25 10:19卍卍
 卐卍卐卍卐卍卐卍卐卍卐卍卐卍卐卍卐卍卐卍卐卍卐卍卐卍卐卍卐卍卐卍卐卍
 *
 *
 */

public class StreamOperationTest {
    List<Employee> employees = Arrays.asList(
            new Employee(101, "张三", 18, 9999.99),
            new Employee(102, "李四", 59, 6666.66),
            new Employee(103, "王五", 38, 7777.77),
            new Employee(104, "赵六", 38, 3333.55),
            new Employee(105, "田七", 44, 5555.55),
            new Employee(105, "田七", 44, 5555.55));

    /**
     * 筛选与切片
     * filter - 接收Lambda，从中排除某些元素。
     * limit - 截断流，使其元素不超过给定数量。
     * skip(n) - 跳过元素，返回一个扔掉了前n个元素的流。若流中元素不足n个，则返回一个空流。与limit(n)互补。
     * distinct - 筛选，通过流所生成元素的hashCode()和equals()去除重复元素。
     */

    // 内部迭代
    @Test
    public void test1() {
        Stream<Employee> stream = employees.stream().filter(e -> {
            System.out.println("Stream API 的中间操作： ");
            return e.getAge() >= 44;
        });
        stream.forEach(System.out::println);
    }

    // 外部迭代
    @Test
    public void test2() {
        Iterator<Employee> iterator = employees.iterator();
        while (iterator.hasNext()) {
            System.out.println(iterator.next());
        }
    }

    // 短路
    @Test
    public void test3() {
        Stream<Employee> limit = employees.stream().filter(e -> {
            System.out.println("短路！！！");
            return e.getSalary() > 5000;
        }).limit(2);
        limit.forEach(System.out::println);
    }

    @Test
    public void test4() {
        Stream<Employee> skip = employees.stream().filter(e -> e.getSalary() > 5000).skip(2);
        skip.forEach(System.out::println);
    }

    @Test
    public void test5() {
        Stream<Employee> distinct = employees.stream().distinct();
        distinct.forEach(System.out::println);
    }

    /**
     * 映射
     * map 接收Lambda，将元素转换成其他形式或提取信息。接收一个函数作为参数，该函数会被应用到每个元素上，并将其映射成一个新元素。
     * flatMap 接收一个函数作为参数，将流中的每个值都换成另外一个流，然后把所有流连接成一个流。
     */
    @Test
    public void test6() {
        List<String> list = Arrays.asList("aa", "bb", "cc", "dd");
        Stream<String> stream = list.stream().map(String::toUpperCase);
        stream.forEach(System.out::println);
        System.out.println("========================================");
        Stream<String> stream1 = employees.stream().map(Employee::getName);
        stream1.forEach(System.out::println);
        System.out.println("========================================");
        Stream<Stream<Character>> streamStream = list.stream().map(StreamOperationTest::filterCharacter);
        streamStream.forEach(s -> s.forEach(System.out::println));
        System.out.println("========================================");
        Stream<Character> characterStream = list.stream().flatMap(StreamOperationTest::filterCharacter);
        characterStream.forEach(System.out::println);

    }

    private static Stream<Character> filterCharacter(String s) {
        List<Character> list = new ArrayList<>();
        for (Character c : s.toCharArray()) {
            list.add(c);
        }
        return list.stream();
    }

}
